Warning: mkdir(): No space left on device in /var/www/tg-me/post.php on line 37

Warning: file_put_contents(aCache/aDaily/post/orgprog/--): Failed to open stream: No such file or directory in /var/www/tg-me/post.php on line 50
Организованное программирование | Кирилл Мокевнин | Telegram Webview: orgprog/309 -
Telegram Group & Telegram Channel
Принцип на все времена: Command-Query Separation

CQS очень простой принцип программирования, применение которого встречается на каждом шагу. Обычно его формулируют так: “задавая вопрос, не изменяй ответ”. Представьте что у вас есть функция, которая проверяет валидность объекта user.isValid(). По смыслу эта функция проверяет данные по каким-то правилам и возвращает true/false.

Может ли она что-то менять? Большинство скажет что это не логично и будет право. Она не должна ничего менять. На практике же, это происходит тут и там. В тех же Rails, вы легко встретите внутри модели колбек before_validation, в котором можно сделать любое изменение, которое сработает на вызов valid?. И этим часто пользуются, я был свидетелем, как в коде удалялись связи у пользователя. Но тоже самое встречается налево и направо у программистов во всех языках.

Однажды, когда я собесил человека на наставника в Хекслет, мы как-то по пути выяснили, что у них там в коде во время запроса каких-то опций, они удалялись из списка опций, мы обсудили этот момент, я чуть-чуть рассказал про CQS и разработчик мне ответил, что после разговора пойдет переписывать код :)

Почему это вообще важно? Тут можно сказать про принцип наименьшего удивления. Код, который меняет что-то на проверку/запрос данных, вводит в ступор всех кто с ним работает. Систему можно проектировать так чтобы этого не было и код делал ровно то, что он заявляет. Есть правда пара исключений, это отложенная инициализация, но снаружи она выгялядит всегда так, как будто изменения не было. И второе, это разного рода аналитика во время работы, например подсчет числа визитов при запросе страницы.

Кстати да, это правило распространяется на все вокруг. Именно поэтому в HTTP существует GET, который можно кешировать так как он сам не меняет данные (но данные могут поменяться по другим причинам), а POST всегда меняет, поэтому кеширование к нему не применяется.

Буквально недавно мы разговаривали с Тагиром и он поделился тем как в Java работает форматирование дат. Оказалось, что в Java есть объект SimpleDateFormat, и он непотокобезопасен. Почему? Потому что метод, который вроде бы просто форматирует дату в строку, на самом деле меняет внутреннее состояние объекта. И если два потока одновременно вызовут .format(…), то они могут получить некорректный результат. Это классический пример нарушения CQS: метод, выглядящий как query (просто возвращает значение), внезапно ведёт себя как command — вносит изменения.

В результате приходится либо каждый раз создавать новый SimpleDateFormat, либо оборачивать его в ThreadLocal, либо использовать DateTimeFormatter из более нового API, который как раз спроектирован с учётом CQS — он ничего не мутирует.

Такие детали, на первый взгляд мелочи, но на практике они и создают разницу между кодом, который легко читать и расширять, и кодом, в котором ты боишься вызвать метод, потому что не знаешь, что он там делает под капотом.

Но это что касается вопросов. А что насчет команд? Тут уже не так очевидно, почему если мы выполняем действие (`setSomething()`, doSomething(), то данные лучше не возвращать?

Во-первых, это снова вопрос читаемости и предсказуемости. Метод с названием deleteUser(id) должен просто удалить пользователя, а не возвращать его профиль. Когда действие возвращает что-то, разработчики начинают полагаться на это значение: передавать его дальше, использовать как флаг, делать выводы.

Во-вторых, это помогает отделить побочные эффекты от чистых вычислений. Когда метод возвращает что-то, возникает иллюзия, что это «безопасно» — можно просто вызвать и использовать результат. Но за кулисами может происходить что угодно: удаление из базы, отправка письма, пересчёт кэша. Такое поведение тяжело тестировать и отлаживать.

Это не значит, что действия никогда ничего не возвращают. Иногда они могут вернуть, например, true или false, чтобы явно показать успех или неудачу. Более того, в некоторых ситуациях невозможно соблюдать CQS, например, при открытии файла на запись (создается файловый дескриптор).

Ссылки: Телеграм | Youtube | VK


p.s. Признавайтесь, писали такой код?



tg-me.com/orgprog/309
Create:
Last Update:

Принцип на все времена: Command-Query Separation

CQS очень простой принцип программирования, применение которого встречается на каждом шагу. Обычно его формулируют так: “задавая вопрос, не изменяй ответ”. Представьте что у вас есть функция, которая проверяет валидность объекта user.isValid(). По смыслу эта функция проверяет данные по каким-то правилам и возвращает true/false.

Может ли она что-то менять? Большинство скажет что это не логично и будет право. Она не должна ничего менять. На практике же, это происходит тут и там. В тех же Rails, вы легко встретите внутри модели колбек before_validation, в котором можно сделать любое изменение, которое сработает на вызов valid?. И этим часто пользуются, я был свидетелем, как в коде удалялись связи у пользователя. Но тоже самое встречается налево и направо у программистов во всех языках.

Однажды, когда я собесил человека на наставника в Хекслет, мы как-то по пути выяснили, что у них там в коде во время запроса каких-то опций, они удалялись из списка опций, мы обсудили этот момент, я чуть-чуть рассказал про CQS и разработчик мне ответил, что после разговора пойдет переписывать код :)

Почему это вообще важно? Тут можно сказать про принцип наименьшего удивления. Код, который меняет что-то на проверку/запрос данных, вводит в ступор всех кто с ним работает. Систему можно проектировать так чтобы этого не было и код делал ровно то, что он заявляет. Есть правда пара исключений, это отложенная инициализация, но снаружи она выгялядит всегда так, как будто изменения не было. И второе, это разного рода аналитика во время работы, например подсчет числа визитов при запросе страницы.

Кстати да, это правило распространяется на все вокруг. Именно поэтому в HTTP существует GET, который можно кешировать так как он сам не меняет данные (но данные могут поменяться по другим причинам), а POST всегда меняет, поэтому кеширование к нему не применяется.

Буквально недавно мы разговаривали с Тагиром и он поделился тем как в Java работает форматирование дат. Оказалось, что в Java есть объект SimpleDateFormat, и он непотокобезопасен. Почему? Потому что метод, который вроде бы просто форматирует дату в строку, на самом деле меняет внутреннее состояние объекта. И если два потока одновременно вызовут .format(…), то они могут получить некорректный результат. Это классический пример нарушения CQS: метод, выглядящий как query (просто возвращает значение), внезапно ведёт себя как command — вносит изменения.

В результате приходится либо каждый раз создавать новый SimpleDateFormat, либо оборачивать его в ThreadLocal, либо использовать DateTimeFormatter из более нового API, который как раз спроектирован с учётом CQS — он ничего не мутирует.

Такие детали, на первый взгляд мелочи, но на практике они и создают разницу между кодом, который легко читать и расширять, и кодом, в котором ты боишься вызвать метод, потому что не знаешь, что он там делает под капотом.

Но это что касается вопросов. А что насчет команд? Тут уже не так очевидно, почему если мы выполняем действие (`setSomething()`, doSomething(), то данные лучше не возвращать?

Во-первых, это снова вопрос читаемости и предсказуемости. Метод с названием deleteUser(id) должен просто удалить пользователя, а не возвращать его профиль. Когда действие возвращает что-то, разработчики начинают полагаться на это значение: передавать его дальше, использовать как флаг, делать выводы.

Во-вторых, это помогает отделить побочные эффекты от чистых вычислений. Когда метод возвращает что-то, возникает иллюзия, что это «безопасно» — можно просто вызвать и использовать результат. Но за кулисами может происходить что угодно: удаление из базы, отправка письма, пересчёт кэша. Такое поведение тяжело тестировать и отлаживать.

Это не значит, что действия никогда ничего не возвращают. Иногда они могут вернуть, например, true или false, чтобы явно показать успех или неудачу. Более того, в некоторых ситуациях невозможно соблюдать CQS, например, при открытии файла на запись (создается файловый дескриптор).

Ссылки: Телеграм | Youtube | VK


p.s. Признавайтесь, писали такой код?

BY Организованное программирование | Кирилл Мокевнин




Share with your friend now:
tg-me.com/orgprog/309

View MORE
Open in Telegram


Организованное программирование | Кирилл Мокевнин Telegram | DID YOU KNOW?

Date: |

A project of our size needs at least a few hundred million dollars per year to keep going,” Mr. Durov wrote in his public channel on Telegram late last year. “While doing that, we will remain independent and stay true to our values, redefining how a tech company should operate.

What is Telegram?

Telegram’s stand out feature is its encryption scheme that keeps messages and media secure in transit. The scheme is known as MTProto and is based on 256-bit AES encryption, RSA encryption, and Diffie-Hellman key exchange. The result of this complicated and technical-sounding jargon? A messaging service that claims to keep your data safe.Why do we say claims? When dealing with security, you always want to leave room for scrutiny, and a few cryptography experts have criticized the system. Overall, any level of encryption is better than none, but a level of discretion should always be observed with any online connected system, even Telegram.

Организованное программирование | Кирилл Мокевнин from cn


Telegram Организованное программирование | Кирилл Мокевнин
FROM USA